<template>
  <div>
    <el-row ref="headerRow"><slot /></el-row>
    <el-row>
      <el-col>
        <span class="buttons-pannel">
          <!-- 切换多选 -->
          <!-- <el-switch
            v-model="isMultiSelect"
            class="duoxuanbtn"
            active-text="多选"
            @change="$refs.theTable.clearSelection()"
          /> -->
          <el-button size="mini" type="default" @click="fetchData"
            >刷新</el-button
          >
          <el-button
            v-if="hasNew"
            size="mini"
            type="primary"
            @click="itemNew()"
            >{{ (buttons[0] && buttons[0].name) || "新建" }}</el-button
          >
          <el-button
            v-if="hasModify"
            size="mini"
            :disabled="isMultiSelect"
            @click="itemUpdate()"
            >{{ (buttons[1] && buttons[1].name) || "修改" }}</el-button
          >
          <el-button
            v-if="hasDelete"
            size="mini"
            type="danger"
            :disabled="
              !(!isMultiSelect && currentRow) &&
              !(isMultiSelect && multipleSelection.length > 0)
            "
            @click="itemDelete()"
            >{{ (buttons[2] && buttons[2].name) || "删除" }}
          </el-button>
          <!-- 自定义按钮 -->
          <el-button
            v-for="btn in customButtons"
            :key="btn.name"
            size="mini"
            :type="btn.type"
            :disabled="btn.isMultiSelect === false && isMultiSelect"
            @click="
              $emit('onCustomButtonClick', {
                target: btn,
                data: {
                  item: currentRow,
                  items: multipleSelection,
                },
              })
            "
            >{{ btn.name }}</el-button
          >
        </span>
        <span>
          <slot name="leftPannel" />
        </span>
        <span class="right-pannel">
          <slot name="rightPannel" />
        </span>
        <span v-if="hasSearchPannel" class="right-pannel">
          <!-- 自定义下拉选框 -->
          <el-select
            v-for="sel in customSelectors"
            :key="sel.name"
            v-model="cuselData[sel.name]"
            :placeholder="sel.name"
            @change="
              $emit('onCustomSelect', {
                target: sel,
                data: cuselData[sel.name],
              })
            "
          >
            <el-option
              v-for="opt in sel.options"
              :key="opt.name"
              :label="opt.name"
              :value="opt.value"
            />
          </el-select>

          <!-- <el-select v-model="searchSelect" placeholder="请选择">
          <el-option label="单条查询" value="text" />
          <el-option label="批量查询" value="textarea" />
        </el-select> -->

          <!-- 按字段过滤 -->
          <el-select v-model="listQuery.queryColumn" placeholder="请选择">
            <el-option
              v-for="col in queriableColnames"
              :key="col.colName"
              :label="col.displayName"
              :value="col.colName"
            />
          </el-select>

          <el-input
            v-model="listQuery.query"
            :type="searchSelect"
            :autosize="{ minRows: 3, maxRows: 6 }"
            :placeholder="
              searchSelect === 'textarea'
                ? '请输入内容，每行一条'
                : '请输入内容'
            "
            class="input-with-select"
            style="display: inline-block"
            @input="fetchData"
            @keyup.enter.native="fetchData"
          />

          <!-- <el-button icon="el-icon-search" @click="fetchData" /> -->
          <el-button
            size="mini"
            icon="el-icon-refresh-left"
            @click="
              listQuery.query = '';
              listQuery.curPage = 1;
              fetchData();
            "
          />
          <el-tag class="tags">共 {{ listData.total }} 条</el-tag>
        </span>
      </el-col>
    </el-row>
    <el-row ref="filters" class="filters"><slot name="filter" /></el-row>
    <el-row class="ltable">
      <el-table
        ref="theTable"
        v-loading.body="isLoading"
        element-loading-text="加载中"
        fit
        stripe
        empty-text="暂无数据"
        :height="windowHeight - 175 - headerHeight + 'px'"
        :data="listData.records"
        border
        highlight-current-row
        @sort-change="onSort"
        @current-change="handleTableCurrentChange"
        @selection-change="handleSelectionChange"
      >
        <el-table-column v-if="isMultiSelect" type="selection" width="55" />
        <el-table-column
          v-for="col in enabledColnames"
          :key="col.colName"
          :sortable="col.sortable"
          :width="col.colWidth"
          :prop="col.colName"
          :label="col.displayName"
        >
          <template slot-scope="scope">
            <!-- 序号类型 -->
            <div v-if="col.dataType === 'indexNo'">
              {{
                scope.$index + (listQuery.curPage - 1) * listQuery.pageSize + 1
              }}
            </div>
            <!-- 日期类型 -->
            <div v-else-if="col.dataType === 'date'">
              {{ getRowData(scope.row, col.colName) | formatDateHM }}
            </div>
            <!-- 性别类型 -->
            <div v-else-if="col.dataType === 'gender'">
              {{ getRowData(scope.row, col.colName) | formatGender }}
            </div>
            <!-- 路由跳转 -->
            <div v-else-if="col.dataType === 'route'">
              <router-link :to="toRoute(col, scope.row)">
                <el-link type="primary">
                  {{ getRowData(scope.row, col.colName) || col.colText }}
                </el-link>
              </router-link>
            </div>
            <!-- 链接点击 -->
            <div v-else-if="col.dataType === 'link'">
              <el-link type="primary" @click="onClick(col, scope.row)">
                {{ getRowData(scope.row, col.colName) || col.colText }}
              </el-link>
            </div>
            <!-- 滑块-->
            <div v-else-if="col.dataType === 'switch'">
              <el-switch
                v-model="scope.row[col.colName]"
                active-color="#13ce66"
                inactive-color="#ff4949"
                @change="changeSwitch(scope.row, col.colName)"
              />
            </div>
            <!-- 图片点击 -->
            <div v-else-if="col.dataType === 'imglink'">
              <el-image
                class="clipimg"
                :src="getRowData(scope.row, col.colName)"
                fit="contain"
                @click="onClick(col, scope.row)"
              />
            </div>
            <!-- 图片 -->
            <div v-else-if="col.dataType === 'image'">
              <el-image
                v-if="getRowData(scope.row, col.colName)"
                class="clipimg"
                :src="getRowData(scope.row, col.colName)"
                fit="contain"
                :preview-src-list="[getRowData(scope.row, col.colName)]"
              />
            </div>
            <!-- 组合字段 -->
            <div v-else-if="col.dataType === 'combine'">
              <span
                v-for="subcol in col.data.cols"
                :key="subcol.name"
                class="oprator"
                >{{ getRowData(scope.row, subcol.name) }}</span
              >
            </div>
            <!-- 是与否 -->
            <div v-else-if="col.dataType === 'bool'">
              <span :class="'color-' + getRowData(scope.row, col.colName)">{{
                getRowData(scope.row, col.colName) | formatBool
              }}</span>
            </div>
            <!-- 操作区 -->
            <div v-else-if="col.dataType === 'oprators'">
              <el-link
                v-for="op in col.data.ops"
                :key="op.name"
                :type="op.type || 'primary'"
                class="oprator"
                @click="onClick(col, scope.row, op)"
              >
                {{ op.name }}
              </el-link>
            </div>
            <!-- 标签类 -->
            <div v-else-if="col.dataType === 'tag'">
              <el-tag
                :type="
                  typeof col.data.type === 'function'
                    ? col.data.type(scope.row, col)
                    : col.data.type
                "
              >
                {{
                  col.formater
                    ? col.formater(
                        getRowData(scope.row, col.colName),
                        scope.row
                      )
                    : getRowData(scope.row, col.colName)
                }}
              </el-tag>
            </div>
            <!-- 默认 -->
            <div v-else>
              {{
                col.formater
                  ? col.formater(getRowData(scope.row, col.colName), scope.row)
                  : getRowData(scope.row, col.colName)
              }}
            </div>
          </template>
        </el-table-column>
      </el-table>
    </el-row>

    <el-row>
      <el-col :span="8">
        <el-pagination
          :current-page.sync="currentPage"
          :page-sizes="[20, 50, 100, 200]"
          :page-size="20"
          layout="sizes, prev, pager, next"
          :total="listData.total"
          @size-change="handleSizeChange"
          @current-change="handleCurrentChange"
        />
      </el-col>
    </el-row>
  </div>
</template>

<style>
.buttons-pannel {
  margin-right: 20px;
}
.right-pannel {
  float: right;
}
.color-true {
  color: green;
}
.color-false {
  color: red;
}
.el-select .el-input {
  width: 130px;
}
.input-with-select {
  width: 260px;
}
.input-with-select .el-input-group__prepend {
  background-color: #fff;
}
.ltable {
  margin-top: 5px;
  margin-bottom: 5px;
}
.tags {
  margin-top: 5px;
  margin-bottom: 5px;
  margin-left: 15px;
}
.clipimg {
  width: 100px;
  height: 100px;
}
.clipimg:hover {
  cursor: pointer;
}
.duoxuanbtn {
  margin-right: 15px;
}
.oprator {
  margin-right: 8px;
}
.filters {
  margin-top: 8px;
}
.el-image-viewer__close {
  color: #fff;
}
</style>

<script>
import { getRowData } from "@/utils";

export default {
  name: "CommonTable",
  props: {
    // 是否多选
    isMultiple: {
      type: Boolean,
      default: false,
    },
    // 是否有新建功能
    hasNew: {
      type: Boolean,
      default: true,
    },
    // 是否有修改功能
    hasModify: {
      type: Boolean,
      default: false,
    },
    // 是否有删除功能
    hasDelete: {
      type: Boolean,
      default: true,
    },
    // 是否有默认搜索栏
    hasSearchPannel: {
      type: Boolean,
      default: false,
    },
    // 默认按钮
    buttons: {
      type: Array,
      default: function () {
        return [{ name: "新建" }, { name: "修改" }, { name: "删除" }];
      },
    },
    // 自定义按钮
    customButtons: {
      type: Array,
      default: function () {
        return [
          // {name: 'buttonname', type:'danger', data: {}}
        ];
      },
    },
    // 自定义选择项
    customSelectors: {
      type: Array,
      default: function () {
        return [
          // {name: 'selName', options: [
          //   {name: 'optino1', value:'value1'},
          //   {name: 'optino2', value:'value2'}
          // ]}
        ];
      },
    },
    // 表头定义
    colnames: {
      type: Array,
      default: function () {
        return [{ displayName: "...", colName: "aa" }];
      },
    },
    // 表数据
    listData: {
      type: Object,
      default: function () {
        return {
          current: 0,
          pages: 0,
          searchCount: true,
          size: 20,
          total: 0,
          records: [],
        };
      },
    },
    // 是否加载中
    listLoading: {
      type: Boolean,
      default: false,
    },
    // 自定义查询
    query: {
      type: Object,
      default: function () {
        return {
          query: "", // 搜索内容
          queryColumn: "", // 搜索列名，即字段名，如：devName, stationName等
          order: "", // 排序，取值：ascending/descending/none(不传Order参数)
          column: "", // 排序列名，即字段名，如：devName, stationName等
          curPage: 1, // 当前页
          pageSize: 20, // 页大小
        };
      },
    },
  },
  data() {
    return {
      currentPage: 0,
      searchInput: "",
      searchSelect: "",
      listQuery: {
        query: "", // 搜索内容
        queryColumn: "", // 搜索列名，即字段名，如：devName, stationName等
        order: "", // 排序，取值：ascending/descending/none(不传Order参数)
        column: "", // 排序列名，即字段名，如：devName, stationName等
        curPage: 1, // 当前页
        pageSize: 20, // 页大小
        queryList: {
          columns: [],
        },
      },
      currentRow: {},
      multipleSelection: [],
      windowHeight: window.innerHeight,
      headerHeight: 0,
      cuselData: {}, // 自定义选项数据
      isMultiSelect: false,
    };
  },
  computed: {
    queriableColnames: function () {
      return this.colnames.filter(
        (item) => item.queryable || (!item.hidden && item.sortable)
      );
    },
    enabledColnames: function () {
      return this.colnames.filter((item) => !item.hidden);
    },
    records: function () {
      if (this.listData && this.listData.records) {
        return this.listData.records;
      }
      return [];
    },
    isLoading: function () {
      return this.listLoading;
    },
  },
  watch: {
    windowHeight(newHeight, oldHeight) {
      // const txt = `window height:  ${oldHeight} -> ${newHeight}  header height: ${this.headerHeight}`
      // console.log(txt)
    },
    isMultiple(newValue) {
      this.isMultiSelect = newValue;
    },
    query: function (newValue) {
      this.listQuery = newValue;
    },
  },
  mounted() {
    this.$nextTick(() => {
      window.addEventListener("resize", this.onResize);
      this.headerHeight = this.$refs.headerRow.$el.offsetHeight;
      this.isMultiSelect = this.isMultiple;
      // console.log('headerHeight', this.$refs, this.$refs.headerRow, this.headerHeight)
    });
  },
  beforeDestroy() {
    window.removeEventListener("resize", this.onResize);
  },
  created() {
    this.listQuery = this.query;
    this.fetchData();
  },
  methods: {
    getRowData: getRowData,
    fetchData() {
      this.$emit("fetchData", this.listQuery);
    },
    // 开关事件
    async changeSwitch(e, str) {
      // console.log(e);
      this.$emit("changeSwitch", { e, str });
    },
    // 改变页大小
    handleSizeChange(size) {
      // console.log(size)
      this.listQuery.curPage = this.currentPage;
      this.listQuery.pageSize = size;
      this.fetchData();
    },
    // 翻页
    handleCurrentChange(curpage) {
      // console.log(curpage)
      this.listQuery.curPage = curpage;
      this.fetchData();
    },
    // 当前选中项改变
    handleTableCurrentChange(val) {
      this.currentRow = val;
      this.$emit("selectChange", {
        type: "one",
        item: this.currentRow,
        items: this.multipleSelection,
      });
    },
    // 当前选中项改变（多选）
    handleSelectionChange(val) {
      if (val.length !== this.multipleSelection.length) {
        // 多选时改变当前选中的行
        this.$refs.theTable.setCurrentRow(val[val.length - 1]);
      }
      this.multipleSelection = val;
      this.$emit("selectChange", {
        type: "multi",
        item: this.currentRow,
        items: this.multipleSelection,
      });
    },
    itemNew() {
      this.$emit("itemNew");
    },
    itemUpdate(row) {
      if (row) {
        // 指定编辑某条记录
        this.currentRow = row;
        this.$emit("itemEdit", {
          type: "one",
          item: this.currentRow,
          items: this.multipleSelection,
        });
        return;
      } else if (!this.isMultiSelect && !this.currentRow.id) {
        this.$message({
          message: "请先选择一条记录再修改!",
          type: "warning",
        });
        return;
      }
      if (this.isMultiSelect) {
        this.$emit("itemEdit", {
          type: "multi",
          item: this.currentRow,
          items: this.multipleSelection,
        });
      } else {
        this.$emit("itemEdit", {
          type: "one",
          item: this.currentRow,
          items: this.multipleSelection,
        });
      }
    },
    itemDelete(row) {
      if (row) {
        // 指定删除某条记录
        console.log(999, row);
        this.currentRow = row;
      } else if (
        (this.isMultiSelect && this.multipleSelection.length === 0) ||
        (!this.isMultiSelect && !this.currentRow.id)
      ) {
        this.$message({
          message: "请先选择一条记录再删除!",
          type: "warning",
        });
        return;
      }

      let msg = "此操作将永久删除该记录, 是否继续?";
      if (this.isMultiSelect && this.multipleSelection.length > 0) {
        msg = `此操作将永久删除这些记录, 共${this.multipleSelection.length}条， 是否继续?`;
      }

      this.$confirm(msg, "提示", {
        confirmButtonText: "确定",
        cancelButtonText: "取消",
        type: "warning",
      })
        .then(() => {
          if (row) {
            this.$emit("itemDelete", { type: "one", item: this.currentRow });
          } else if (this.isMultiSelect) {
            this.$emit("itemDelete", {
              type: "multi",
              items: this.multipleSelection,
            });
          } else {
            this.$emit("itemDelete", { type: "one", item: this.currentRow });
          }
        })
        .catch(() => {
          this.$message({
            type: "info",
            message: "已取消删除",
          });
        });
    },
    onSort({ column, prop, order }) {
      console.log("onSort", column, prop, order);
      this.listQuery.column = prop;
      this.listQuery.order = order || "";
      this.fetchData();
    },
    onResize() {
      this.windowHeight = window.innerHeight;
    },
    toRoute(col, row) {
      // console.log('toRoute', col, row)
      const ret = {};
      ret.name = col.route.name;
      ret.params = {};
      Object.keys(col.route.params).forEach((key) => {
        ret.params[key] = row[col.route.params[key]];
        ret.params.fromItem = row;
      });
      return ret;
    },
    onClick(col, row, op) {
      if (op) {
        if (op.click) {
          this[op.click](row);
        }
        this.$emit("onItemClick", { col, row, op });
      } else {
        this.$emit("onItemClick", { col, row });
      }
    },
  },
};
</script>
